
#include "stdafx.h"
#include "modulestree.h"
#include "profilingthread.h"

mod_vec_t __mods_vec;
CTreeViewCtrl __treeViewCtrl;

HMODULE get_module_handle_by_addr( DWORD addr )
{
	int n = __mods_vec.size();

	for( int i = 0;i<n;i++ )
	{
		if( !__mods_vec[i].is_reference )
		{
			int offset = (int)addr - (int)__mods_vec[i].base_addr; 
			int size = __mods_vec[i].size;
			if( offset >=0 )
				if( offset< size )
					return __mods_vec[i].instance;
		}
	}

	return NULL;
	
}

void add_mod_bytes( int idx,int dwBytes )
{
	if( idx>=0 )
	{
		InterlockedExchangeAdd ( &__mods_vec[idx].usrlong,(long) dwBytes );
		::PostMessage( __hwnd_dlg,WM_MPROFILER_MESSAGE,idx,0 );
	}
}

int find_mod_path( HMODULE* pmods,int cmods )
{
	if( cmods == 0 )
		return -1;

	int c_mods_vec = __mods_vec.size();
	int idx = -1;

	static HMODULE root = NULL;
	if(!root)
		root = ::GetModuleHandleA( NULL );

	static HMODULE kernel = NULL;
	if( !kernel)
		kernel = ::GetModuleHandleA( "kernel32.dll" );

	int find_i = -1;
	
	for( int i = 0;i<cmods;i++ )
	{
		HMODULE hm = pmods[i];

		if( hm == kernel )
			break;

		int find_j = -1;
		for( int j = 0;j<c_mods_vec;j++ )
		{	
			if( __mods_vec[j].hrk == i && __mods_vec[j].instance == hm )
			{
				find_j = j;
				break;
			}
		}

		int find_jr = -1;

		if( find_j < 0 )
		{
#if 0
			
			for( int j = 0;j<c_mods_vec;j++ )
			{	
				if( __mods_vec[j].is_reference )
				{
					if( __mods_vec[j].hrk == i && __mods_vec[j].instance == hm )
					{
						find_jr = j;
						break;
					}
				}
			}
			find_i = -1;
#endif
			break;
		}

		if( find_jr>=0 )
		{
			find_i = find_jr;
			break;
		}
		else
		{
			find_i = find_j;
		}
	}

	if( find_i >=0 )
	{
		find_i = find_i;
	}

	return find_i;
}

void init_tree_ctrl(HWND hwnd )
{
	__treeViewCtrl.Attach( hwnd );
}

void clear_modules_tree()
{
	__treeViewCtrl.DeleteAllItems();
}



void set_modules_tree_item( int idx,bool update )
{
	char bufxxx[64];
	CTreeViewCtrl& tree_ctrl = __treeViewCtrl ;
	HTREEITEM htx = (HTREEITEM)__mods_vec[idx].usrptr;
	char bufx[512] = "";	

	if( __mods_vec[idx].is_reference )
		strcat( bufx,"^");
	strcat( bufx,__mods_vec[idx].name );
	
	if( update )
	{
		LONG memsize = __mods_vec[idx].usrlong;
	
		if( memsize>0)
		{
			strcat( bufx,"-----------");
			strcat( bufx,ntos(bufxxx,memsize));
			tree_ctrl.SetItemText( htx,bufx );
		}

		
	}
	else
	{
		tree_ctrl.SetItemText( htx,bufx );
	}
}

void expand_modules_tree()
{
	__treeViewCtrl.ExpandTree( __treeViewCtrl.GetRootItem(),TVE_EXPAND );
}

void create_modules_tree( mod_vec_t& mod_vec )
{
	CTreeViewCtrl& tree_ctrl = __treeViewCtrl ;

	int n = mod_vec.size();

	for( int i = 0;i<n;i++ )
	{
		mod_vec[i].usrptr = NULL;
		mod_vec[i].usrlong = 0;
	}

	char buf[MAX_PATH];
	
	HTREEITEM ht_parent = TVI_ROOT;

	std::vector<HINSTANCE> created_inst_vec;
	created_inst_vec.resize(n);

	std::vector<HTREEITEM> created_item_vec; 
	created_item_vec.resize(n);

	int pid = -1;

	for( int i = 0;i<n;i++ )
	{
		created_inst_vec[i] = NULL;
		created_item_vec[i] = NULL;
	}
	
	for( int i = 0;i<n;i++ )
	{
		HTREEITEM ht_last = TVI_LAST;	
		
		if( created_item_vec[mod_vec[i].idx] )
			continue;
	
		pid = mod_vec[i].p_id;
		int pidx = pid;
		if( pidx >= 0 )
		{
			if( mod_vec[pidx].is_reference )
			{
				for( int j = 0;j<n;j++ )
				{
					if( mod_vec[j].instance == mod_vec[pidx].instance )
					{
						if( !mod_vec[j].is_reference )
						{
							pidx = j;
							break;
						}
					}
				}
			}

			ht_parent = created_item_vec[pidx];
		}
		
		for( int j = 0;j<n;j++ )
		{
			if( mod_vec[j].p_id == pid )
			{			
				HTREEITEM htx = tree_ctrl.InsertItem( "",ht_parent,ht_last );

				ht_last = htx;

				int idx = mod_vec[j].idx;
				created_inst_vec[idx] = mod_vec[j].instance;
				created_item_vec[idx] = htx;
				mod_vec[j].usrptr = (void*) htx;

				set_modules_tree_item(j,false);		
			}
		}
	}
}
